import pygame
import pygame.mixer
import sys
import random
import time
from pygame.locals import *
import maze
import color
from task import Task  # 导入task.py中的Task类
import json


def load_config(file_path):
    with open(file_path, 'r') as file:
        config = json.load(file)
    return config

config = load_config("config.json")
# 全局变量定义
screen_width = config["screen"]["width"]
screen_height = config["screen"]["height"]
exit_x = config["exit"]["x"]
exit_y = config["exit"]["y"]
exit_width = config["exit"]["width"]
exit_height = config["exit"]["height"]
exit_text = config["exit"]["text"]
ai_x = config["ai"]["x"]
ai_y = config["ai"]["y"]
ai_width = config["ai"]["width"]
ai_height = config["ai"]["height"]
ai_text = "AI"
x, y = 27, 30

# 玩家移动路径的栈
move_stack = []

# 用于存储多个任务点的位置
task_points = []

# 标志变量，用于跟踪是否显示确认窗口
confirm_window_shown = False

# 玩家原来所在的迷宫位置
previous_x, previous_y = 27, 30

# 标志变量，是否显示返回按钮
show_return_button = False

# 返回按钮位置
go_back_x = config["go_back"]["x"]
go_back_y = config["go_back"]["y"]
go_back_width = config["go_back"]["width"]
go_back_height = config["go_back"]["height"]
go_back_text = config["go_back"]["text"]
nesting_level = 0  # 当前嵌套层数
max_nesting_level = 3  # 最大允许嵌套层数


def print_text(font, x, y, text, color, shadow=True):
    if shadow:
        imgText = font.render(text, True, (0, 0, 0))
        screen.blit(imgText, (x - 2, y - 2))
    imgText = font.render(text, True, color)
    screen.blit(imgText, (x, y))

def draw_main_maze_with_markers():
    """绘制主迷宫并添加起点、终点标记以及所有任务点"""
    screen.fill(color.White)

    # 绘制迷宫中的所有房间
    for i in range(maze.room_m):
        for j in range(maze.room_n):
            begin_point = [25 + i * maze.room_size, 25 + j * maze.room_size]
            r_color = color.Black
            maze.room.draw_room(screen, begin_point, r_list[i][j].walls, maze.room_size, r_color)

    # 绘制起点标记
    pygame.draw.rect(screen, color.Green, (27, 30, maze.room_size - 6, maze.room_size - 6))

    # 绘制终点标记
    end_x = 25 + (maze.room_m - 1) * maze.room_size + 3
    end_y = 25 + (maze.room_n - 1) * maze.room_size + 3
    pygame.draw.rect(screen, color.Red, (end_x, end_y, maze.room_size - 6, maze.room_size - 6))

    # 绘制任务点
    task_images = [pygame.image.load("task.png").convert_alpha()]
    task_image = pygame.transform.smoothscale(task_images[0], (10, 10))
    for task_point in task_points:
        task_x_pos = 25 + task_point[0] * maze.room_size
        task_y_pos = 25 + task_point[1] * maze.room_size
        task_icon_x = task_x_pos + (maze.room_size - task_image.get_width()) // 2
        task_icon_y = task_y_pos + (maze.room_size - task_image.get_height()) // 2
        screen.blit(task_image, (task_icon_x, task_icon_y))

    # 绘制玩家当前位置
    screen.blit(player, (x, y))
    pygame.display.update()


def reset_game():
    global nesting_level
    nesting_level = 0
    global r_list, player, x, y, roomx, roomy, maze_steps, task_points, current_task, move_stack, previous_x, previous_y,player_points,show_return_button
    # 清空栈和任务点列表
    move_stack.clear()
    task_points.clear()

    # 重新生成迷宫
    r_list = maze.room.creat_map(maze.room_m, maze.room_n)
    begin_point = [0, 0]
    begin_room = r_list[0][0]
    maze.room.creat_migong(r_list, begin_room, maze.room_m, maze.room_n)  # 传递行数和列数

    r_list[0][0].walls[0] = False  # 起点上墙
    r_list[0][0].walls[3] = False # 起点左墙
    r_list[maze.room_m - 1][maze.room_n - 1].walls[1] = False # 终点右墙
    r_list[maze.room_m - 1][maze.room_n - 1].walls[2] = False # 终点下墙

    # 随机生成多个任务点
    num_tasks = random.randint(10, 20)
    for _ in range(num_tasks):
        # 随机生成任务点的坐标，确保在迷宫的有效范围内
        task_x = random.randint(0, maze.room_m - 1)
        task_y = random.randint(0, maze.room_n - 1)
        task_points.append((task_x, task_y))

    # 创建任务图标
    task_images = [pygame.image.load("task.png").convert_alpha()]
    task_image = pygame.transform.smoothscale(task_images[0], (10, 10))

    # 清空屏幕并重新绘制
    screen.fill(color.White)
    for i in range(maze.room_m):
        for j in range(maze.room_n):
            begin_point[0] = 25 + i * maze.room_size
            begin_point[1] = 25 + j * maze.room_size
            r_color = color.Black
            maze.room.draw_room(screen, begin_point, r_list[i][j].walls, maze.room_size, r_color)

    # 画起点和终点
    maze.room.draw_room(screen, [25, 25], [0, 0, 0, 1], maze.room_size, color.White)
    maze.room.draw_room(screen, [25 + (maze.room_m - 1) * maze.room_size, 25 + (maze.room_n - 1) * maze.room_size],
                        [0, 1, 0, 0], maze.room_size, color.White)

    # 绘制多个任务点
    for task_point in task_points:
        task_x_pos = 25 + task_point[0] * maze.room_size
        task_y_pos = 25 + task_point[1] * maze.room_size
        task_icon_x = task_x_pos + (maze.room_size - task_image.get_width()) // 2
        task_icon_y = task_y_pos + (maze.room_size - task_image.get_height()) // 2
        screen.blit(task_image, (task_icon_x, task_icon_y))

    # 初始化玩家位置和步数
    if previous_x is not None and previous_y is not None:
        x, y = previous_x, previous_y  # 将玩家位置重置为上一个迷宫的位置
    else:
        x, y = 27, 30  # 重置玩家位置到起点

    roomx, roomy = 0, 0
    maze_steps = 0
    player_points = 0  # 重置玩家分数
    move_stack.append((x, y))  # 将玩家初始位置压入栈中
    screen.blit(player, (x, y))
    show_return_button = True  # 显示返回按钮
    pygame.display.flip()

def ai_move():
    global x, y, roomx, roomy, maze_steps, player_points
    stack = []  # 用于保存路径
    visited = set()  # 用于记录已访问的房间
    path = []  # 用于留痕的路径
    start_x, start_y = roomx, roomy  # 从当前玩家位置开始

    # 初始化栈，将起点压入栈中
    stack.append((start_x, start_y))
    visited.add((start_x, start_y))

    # 用于记录找到出口的路径
    exit_path = []

    # 初始化 path_trail，用于记录光标的痕迹
    path_trail = []

    while stack:
        # 获取当前房间的位置
        current_x, current_y = stack[-1]
        # 检查是否到达出口
        if current_x == maze.room_m - 1 and current_y == maze.room_n - 1:
            print("AI found the exit!")
            exit_path = path.copy()  # 记录找到出口的路径
            break  # 找到出口后退出循环

        # 尝试移动到四个方向
        moved = False
        for direction in range(4):  # 0: 上, 1: 右, 2: 下, 3: 左
            if direction == 0 and not r_list[current_x][current_y].walls[0]:  # 上
                next_x, next_y = current_x, current_y - 1
            elif direction == 1 and not r_list[current_x][current_y].walls[1]:  # 右
                next_x, next_y = current_x + 1, current_y
            elif direction == 2 and not r_list[current_x][current_y].walls[2]:  # 下
                next_x, next_y = current_x, current_y + 1
            elif direction == 3 and not r_list[current_x][current_y].walls[3]:  # 左
                next_x, next_y = current_x - 1, current_y
            else:
                continue

            # 检查下一个位置是否已访问过
            if (next_x, next_y) not in visited:
                if current_x == 0 and next_x == -1:  # 确保AI不进入起点左边
                    continue
                if current_y == 0 and next_y == -1:  # 确保AI不进入起点上边
                    continue
                # 移动到下一个位置
                stack.append((next_x, next_y))
                visited.add((next_x, next_y))
                path.append((next_x, next_y))  # 将路径记录下来
                roomx, roomy = next_x, next_y
                x = 27 + roomx * maze.room_size
                y = 30 + roomy * maze.room_size
                maze_steps += 1
                moved = True
                break  # 结束当前循环，继续处理新位置

        # 如果没有可行的方向，回溯
        if not moved:
            last_x, last_y = stack.pop()  # 回到上一个位置
            if path:  # 如果路径列表非空
                path.pop()  # 移除当前的路径记录

    # 如果找到了出口路径
    if exit_path:
        # 清空屏幕
        #screen.fill(color.White)
        #draw_main_maze_with_markers()

        # 只显示找到的唯一解路径
        for px, py in exit_path:
            path_x = 27 + px * maze.room_size
            path_y = 30 + py * maze.room_size
            screen.blit(player, (path_x, path_y))  # 在路径上绘制光标
            pygame.display.update()

            # 持续记录路径痕迹，不清空path_trail
            path_trail.append((path_x, path_y))

            time.sleep(0.1)  # 等待，模拟AI移动的时间

            # 检查是否触发任务点
            success, player_points = check_task_trigger(path_x, path_y, task_points, player_points)
            if success:
                # 任务完成后继续 AI 移动
                draw_main_maze_with_markers()
                screen.blit(player, (path_x, path_y))
                pygame.display.update()
                time.sleep(1)  # 暂停一会儿，模拟任务处理时间

        # 在所有路径上绘制光标痕迹
            for px, py in path_trail:
                screen.blit(player, (px, py))
            pygame.display.update()

        # 更新最终位置
        roomx, roomy = maze.room_m - 1, maze.room_n - 1
        x = 27 + roomx * maze.room_size
        y = 30 + roomy * maze.room_size
        screen.blit(player, (x, y))
        pygame.display.update()

        player_points = 0  # 重置分数
        return True  # 找到出口
        draw_main_maze_with_markers()

        screen.blit(player, (x, y))  # 绘制AI当前位置
        print_text(pygame.font.Font(None, 32), 25, 0, "Steps: " + str(maze_steps), color.Black)
        pygame.display.update()
        time.sleep(0.1)  # 等待，模拟AI移动的时间

    return False  # 如果栈为空，表示没有找到出口


def display_task_prompt(task):
    """
    显示是否要进行任务的提示，返回玩家的选择（True 代表接受任务，False 代表拒绝）
    """
    prompt_window = pygame.Surface((300, 100))
    prompt_window.fill(color.Gray)
    font = pygame.font.Font(None, 24)
    prompt_text = font.render("Do you want to start this task? (Y/N)", True, color.Black)
    prompt_window.blit(prompt_text, (10, 40))

    # 保存当前屏幕以便后续恢复
    previous_screen = screen.copy()

    while True:
        # 显示提示窗口
        screen.blit(prompt_window, (50, 50))
        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_y:  # 玩家选择接受任务
                    return True
                elif event.key == pygame.K_n or event.key == pygame.K_ESCAPE:  # 玩家选择拒绝任务或按下 ESC 键
                    # 恢复原始屏幕
                    screen.blit(previous_screen, (0, 0))
                    pygame.display.update()
                    return False

def handle_small_maze_task(small_r_list, small_maze_size):
    global nesting_level

    # 检查是否超过最大嵌套层数
    if nesting_level >= max_nesting_level:
        print("Reached maximum nesting level!")
        return False
    else:
        task_positions = generate_task_positions(small_r_list, small_maze_size, num_tasks=random.randint(3, 5))

    # 增加当前嵌套层数
    nesting_level += 1
    """处理小迷宫任务"""
    small_roomx, small_roomy = 0, 0  # 小迷宫起点
    small_x, small_y = 50 + small_roomx * maze.room_size, 50 + small_roomy * maze.room_size

    while True:
        display_small_maze(small_r_list, small_maze_size, task_positions)
        display_nesting_level()
        # 绘制玩家光标
        screen.blit(player, (small_x, small_y))
        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == pygame.KEYDOWN:
                if (small_roomx, small_roomy) == (0, 0):
                    if event.key == pygame.K_UP:  # 起点禁止向上
                        font = pygame.font.Font(None, 32)
                        screen.fill(color.White, (150, 0, 200, 25))
                        print_text(font, 150, 0, "Can't move up from the start!", color.Black)
                        continue
                    elif event.key == pygame.K_LEFT:  # 起点禁止向右
                        font = pygame.font.Font(None, 32)
                        screen.fill(color.White, (150, 0, 200, 25))
                        print_text(font, 150, 0, "Can't move right from the start!", color.Black)
                        continue
                # 控制玩家在小迷宫中移动
                if event.key == pygame.K_RIGHT and not small_r_list[small_roomx][small_roomy].walls[1]:
                    small_roomx += 1
                    footstep_sound.play()
                elif event.key == pygame.K_LEFT and not small_r_list[small_roomx][small_roomy].walls[3]:
                    small_roomx -= 1
                    footstep_sound.play()
                elif event.key == pygame.K_UP and not small_r_list[small_roomx][small_roomy].walls[0]:
                    small_roomy -= 1
                    footstep_sound.play()
                elif event.key == pygame.K_DOWN and not small_r_list[small_roomx][small_roomy].walls[2]:
                    small_roomy += 1
                    footstep_sound.play()

                # 更新玩家位置并重新绘制小迷宫
                small_x = 50 + small_roomx * maze.room_size
                small_y = 50 + small_roomy * maze.room_size

                # 检查是否触发任务点
                if nesting_level < max_nesting_level:
                    player_rect = pygame.Rect(small_x, small_y, player.get_width(), player.get_height())
                    for task_pos in task_positions:
                        task_x, task_y = 50 + task_pos[0] * maze.room_size + 3, 50 + task_pos[1] * maze.room_size + 3
                        task_rect = pygame.Rect(task_x, task_y, maze.room_size - 6, maze.room_size - 6)

                        if player_rect.colliderect(task_rect):
                            task = Task.generate_random_task(1, task_pos)  # 随机生成任务
                            if task.task_type == 'math':  # 数学题任务
                                success, _ = display_task_window(task, player_points)
                                if success:
                                    task_positions.remove(task_pos)  # 任务完成后移除任务点
                                    break
                            elif task.task_type == 'maze':  # 生成更小的迷宫
                                new_small_r_list, new_small_maze_size = generate_small_maze()
                                success = handle_small_maze_task(new_small_r_list, new_small_maze_size)
                                if success:
                                    task_positions.remove(task_pos)  # 移除任务点
                                    break
                # 检查是否到达小迷宫出口
                if small_roomx == small_maze_size - 1 and small_roomy == small_maze_size - 1:
                    nesting_level -= 1
                    return True  # 完成小迷宫任务

def get_max_nesting_level():
    """显示一个弹窗，让玩家输入最大嵌套层数"""
    font = pygame.font.Font(None, 36)
    input_box = pygame.Rect(screen_width // 2 - 100, screen_height // 2 - 25, 200, 50)
    color_active = pygame.Color('lightskyblue3')
    color_inactive = pygame.Color('gray15')
    text_color = pygame.Color('black')
    color = color_inactive
    active = False
    text = ''
    error_message = ''
    max_level = 1

    while True:
        # 填充屏幕背景为白色
        screen.fill((255, 255, 255))

        # 显示提示文本
        title_text = font.render("Enter max maze level (1-5):", True, text_color)
        screen.blit(title_text, (screen_width // 2 - title_text.get_width() // 2, screen_height // 2 - 100))

        # 绘制输入框
        pygame.draw.rect(screen, color, input_box, 2)

        # 显示输入内容
        input_text = font.render(text, True, text_color)
        screen.blit(input_text, (input_box.x + 10, input_box.y + 10))

        # 显示错误信息（如果有）
        if error_message:
            error_text = font.render(error_message, True, pygame.Color('red'))
            screen.blit(error_text, (screen_width // 2 - error_text.get_width() // 2, screen_height // 2 + 50))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 如果鼠标点击输入框，则激活
                if input_box.collidepoint(event.pos):
                    active = not active
                else:
                    active = False
                color = color_active if active else color_inactive

            elif event.type == pygame.KEYDOWN:
                if active:
                    if event.key == pygame.K_RETURN:
                        try:
                            max_level = int(text)
                            if 1 <= max_level <= 5:
                                return max_level
                            else:
                                error_message = "Invalid! Enter a number between 1 and 5"
                                text = ''  # 清空输入框内容
                        except ValueError:
                            error_message = "Invalid! Enter a valid number"
                            text = ''  # 清空输入框内容
                    elif event.key == pygame.K_BACKSPACE:
                        text = text[:-1]
                    else:
                        text += event.unicode

        pygame.display.flip()


def display_nesting_level():
    """显示当前嵌套层数在右下角"""
    font = pygame.font.Font(None, 24)
    text = f"Level: {nesting_level}"
    text_surface = font.render(text, True, color.Black)

    # 计算显示位置（右下角）
    text_x = screen_width - text_surface.get_width() - 10
    text_y = screen_height - text_surface.get_height() - 10

    # 绘制背景框
    pygame.draw.rect(screen, color.Gray, (text_x - 5, text_y - 5, text_surface.get_width() + 10, text_surface.get_height() + 10))

    # 显示文本
    screen.blit(text_surface, (text_x, text_y))

def display_task_window(task, player_points):
    task_window = pygame.Surface((300, 200))
    task_window.fill(color.Gray)

    font = pygame.font.Font(None, 24)
    task_description = font.render(task.description, True, color.Black)
    task_window.blit(task_description, (10, 10))

    input_box = pygame.Rect(10, 50, 200, 30)
    pygame.draw.rect(task_window, color.White, input_box)
    input_text = ''
    feedback = None

    # 保存当前屏幕以便后续恢复
    previous_screen = screen.copy()

    while True:
        # 显示任务窗口
        screen.blit(task_window, (50, 50))
        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    if task.check_answer(input_text):
                        # 如果回答正确
                        feedback = "Correct!"
                        correct_sound.play()
                        player_points += task.get_reward()
                        task_window.fill(color.Gray)
                        feedback_surface = font.render(feedback, True, color.Green)
                        task_window.blit(feedback_surface, (10, 150))
                        screen.blit(task_window, (50, 50))
                        pygame.display.update()
                        pygame.time.wait(1000)  # 暂停1秒显示反馈
                        # 恢复原始屏幕
                        screen.blit(previous_screen, (0, 0))
                        pygame.display.update()
                        return True, player_points  # 返回成功状态和更新分数
                    else:
                        # 如果回答错误
                        wrong_sound.play()
                        feedback = "Error!"
                        task_window.fill(color.Gray)
                        task_window.blit(task_description, (10, 10))
                        feedback_surface = font.render(feedback, True, color.Red)
                        task_window.blit(feedback_surface, (10, 150))
                        screen.blit(task_window, (50, 50))
                        pygame.display.update()
                        pygame.time.wait(1000)  # 暂停1秒显示反馈
                        input_text = ''  # 清空输入，玩家可以重新作答

                elif event.key == pygame.K_BACKSPACE:
                    input_text = input_text[:-1]
                elif event.key == pygame.K_ESCAPE:
                    # 按下 ESC 键关闭任务窗口并恢复原始屏幕
                    screen.blit(previous_screen, (0, 0))
                    pygame.display.update()
                    return False, player_points
                else:
                    input_text += event.unicode

            # 更新输入框内容
            pygame.draw.rect(task_window, color.White, input_box)
            txt_surface = font.render(input_text, True, color.Black)
            task_window.blit(txt_surface, (input_box.x + 5, input_box.y + 5))



    return False, player_points  # 返回失败状态并保持当前分数

# 玩家与任务点碰撞检测
def check_task_trigger(x, y, task_points, player_points):
    """
    检查玩家是否到达任务点，如果到达，则生成一个任务并触发任务窗口。
    """
    for task_point in task_points:
        # 计算任务点的位置
        task_x_pos = 25 + task_point[0] * maze.room_size
        task_y_pos = 25 + task_point[1] * maze.room_size
        task_rect = pygame.Rect(task_x_pos, task_y_pos, maze.room_size, maze.room_size)

        # 检查玩家是否与任务点重叠
        player_rect = pygame.Rect(x, y, player.get_width(), player.get_height())
        if task_rect.colliderect(player_rect):
            # 光标与任务点重叠
            task = Task.generate_random_task(1, task_point)  # 随机生成一个任务
            if task.task_type == 'math':  # 数学题任务
                if display_task_prompt(task):  # 显示提示，玩家选择是否接受任务
                    success, player_points = display_task_window(task, player_points)
                    if success:
                        task_points.remove(task_point)  # 任务完成后移除任务点
                    return success, player_points

            elif task.task_type == 'maze':  # 小迷宫任务
                if display_task_prompt(task):  # 显示提示，玩家选择是否接受任务
                    # 生成并处理小迷宫任务
                    small_r_list, small_maze_size = generate_small_maze()
                    success = handle_small_maze_task(small_r_list, small_maze_size)
                    if success:
                        player_points += task.get_reward()  # 完成任务奖励
                        task_points.remove(task_point)  # 任务完成后移除任务点
                    return success, player_points

    return None, player_points
def draw_task_points(task_points, task_image):
    """
    绘制所有未完成的任务点。
    """
    for task_point in task_points:
        # 计算任务点的位置
        task_x_pos = 25 + task_point[0] * maze.room_size
        task_y_pos = 25 + task_point[1] * maze.room_size

        # 计算任务图标的绘制位置
        task_icon_x = task_x_pos + (maze.room_size - task_image.get_width()) // 2
        task_icon_y = task_y_pos + (maze.room_size - task_image.get_height()) // 2

        # 绘制任务点图标
        screen.blit(task_image, (task_icon_x, task_icon_y))


def generate_small_maze():
    """生成一个小迷宫"""
    # 随机生成小迷宫的大小，范围为 3x3 到 7x7
    small_maze_size = random.randint(3, 7)

    # 创建小迷宫的房间列表
    small_r_list = maze.room.creat_map(small_maze_size, small_maze_size)
    begin_room = small_r_list[0][0]
    maze.room.creat_migong(small_r_list, begin_room, small_maze_size, small_maze_size)

    # 确保小迷宫起点和终点没有墙
    small_r_list[0][0].walls[3] = False  # 起点左墙
    small_r_list[0][0].walls[0] = False  # 起点上墙
    small_r_list[small_maze_size - 1][small_maze_size - 1].walls[1] = False  # 终点右墙
    small_r_list[small_maze_size - 1][small_maze_size - 1].walls[2] = False  # 终点下墙

    return small_r_list, small_maze_size

def generate_task_positions(small_r_list, small_maze_size, num_tasks=3):
    """随机生成任务点的位置"""
    task_positions = []
    while len(task_positions) < num_tasks:
        x = random.randint(0, small_maze_size - 1)
        y = random.randint(0, small_maze_size - 1)
        if (x, y) != (0, 0) and (x, y) != (small_maze_size - 1, small_maze_size - 1):
            task_positions.append((x, y))
    return task_positions

def display_small_maze(small_r_list, small_maze_size, task_positions=None):
    """显示小迷宫"""
    screen.fill(color.White)
    for i in range(small_maze_size):
        for j in range(small_maze_size):
            begin_point = [50 + i * maze.room_size, 50 + j * maze.room_size]
            r_color = color.Black
            maze.room.draw_room(screen, begin_point, small_r_list[i][j].walls, maze.room_size, r_color)

    # 绘制起点标记
    start_x = 50 + 3  # 起点坐标
    start_y = 50 + 3
    pygame.draw.rect(screen, color.Green, (start_x, start_y, maze.room_size - 6, maze.room_size - 6))

    # 绘制终点标记
    end_x = 50 + (small_maze_size - 1) * maze.room_size + 3
    end_y = 50 + (small_maze_size - 1) * maze.room_size + 3
    pygame.draw.rect(screen, color.Red, (end_x, end_y, maze.room_size - 6, maze.room_size - 6))


    # 检查是否超过最大嵌套层数
    if nesting_level >= max_nesting_level:
        print("Reached maximum nesting level!")
        return False
    else:
        if task_positions:
            task_image = pygame.image.load("task.png")  # 加载任务点图标
            task_image = pygame.transform.scale(task_image, (maze.room_size - 6, maze.room_size - 6))  # 调整图标大小
            for task_pos in task_positions:
                task_x = 50 + task_pos[0] * maze.room_size + 3
                task_y = 50 + task_pos[1] * maze.room_size + 3
                screen.blit(task_image, (task_x, task_y))  # 绘制任务点图标


def display_win_confirm():
    """
    显示胜利确认窗口，玩家选择是否进入下一个迷宫
    """
    global confirm_window_shown

    confirm_window = pygame.Surface((300, 100))
    confirm_window.fill(color.Gray)
    font = pygame.font.Font(None, 24)
    confirm_text = font.render("You Win! Enter next maze? (Y/N)", True, color.Black)
    confirm_window.blit(confirm_text, (10, 40))

    # 保存当前屏幕以便后续恢复
    previous_screen = screen.copy()

    while True:
        # 显示确认窗口
        screen.blit(confirm_window, (50, 50))
        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_y:  # 玩家选择进入下一个迷宫
                    confirm_window_shown = False
                    return True
                elif event.key == pygame.K_n or event.key == pygame.K_ESCAPE:  # 玩家选择留在当前迷宫或按下 ESC 键
                    screen.blit(previous_screen, (0, 0))
                    pygame.display.update()
                    confirm_window_shown = False
                    return False


def show_main_menu():
    # 加载封面背景图片
    background = pygame.image.load("fengmian.png").convert()
    background = pygame.transform.scale(background, (screen_width, screen_height))

    """显示游戏主菜单"""
    font = pygame.font.Font(None, 50)
    button_font = pygame.font.Font(None, 36)

    # 设置按钮
    rule_button = pygame.Rect(screen_width // 2 - 100, screen_height // 2 - 150, 200, 50)  # 新增“游戏规则”按钮
    set_maze_button = pygame.Rect(screen_width // 2 - 100, screen_height // 2 - 50, 200, 50)
    start_game_button = pygame.Rect(screen_width // 2 - 100, screen_height // 2 + 20, 200, 50)

    max_nesting_level = None  # 嵌套层数，等待设置

    while True:
        screen.fill((255, 255, 255))  # 背景填充白色
        screen.blit(background, (0, 0))
        # 显示标题
        title_text = font.render("Maze Game", True, (0, 0, 159))
        screen.blit(title_text, (screen_width // 2 - title_text.get_width() // 2, 100))

        # 绘制“游戏规则”按钮
        pygame.draw.rect(screen, (255, 128, 0), rule_button)
        rule_text = button_font.render("Game Rules", True, (255, 255, 255))
        screen.blit(rule_text, (rule_button.x + 40, rule_button.y + 10))

        # 绘制“设置迷宫”按钮
        pygame.draw.rect(screen, (0, 128, 255), set_maze_button)
        set_maze_text = button_font.render("Set Maze", True, (255, 255, 255))
        screen.blit(set_maze_text, (set_maze_button.x + 50, set_maze_button.y + 10))

        # 绘制“开始游戏”按钮
        pygame.draw.rect(screen, (0, 255, 128), start_game_button)
        start_game_text = button_font.render("Start Game", True, (255, 255, 255))
        screen.blit(start_game_text, (start_game_button.x + 40, start_game_button.y + 10))

        # 显示嵌套层数（如果已设置）
        if max_nesting_level is not None:
            nesting_text = button_font.render(f"Max Nesting: {max_nesting_level}", True, (0, 0, 0))
            screen.blit(nesting_text, (screen_width // 2 - nesting_text.get_width() // 2, screen_height // 2 - 120))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 点击“游戏规则”按钮
                if rule_button.collidepoint(event.pos):
                    show_game_rules()
                # 点击“设置迷宫”按钮
                if set_maze_button.collidepoint(event.pos):
                    max_nesting_level = get_max_nesting_level()

                # 点击“开始游戏”按钮
                elif start_game_button.collidepoint(event.pos):
                    if max_nesting_level is not None:
                        return max_nesting_level
                    else:
                        # 提示玩家先设置迷宫层数
                        nesting_text = button_font.render("Set Maze First!", True, (255, 0, 0))
                        screen.blit(nesting_text,
                                    (screen_width // 2 - nesting_text.get_width() // 2, screen_height // 2 + 80))
                        pygame.display.update()
                        pygame.time.wait(1000)  # 显示提示 1 秒后继续

        pygame.display.update()
def show_game_rules():
    """显示游戏规则界面"""
    font = pygame.font.Font(None, 24)
    rules = [
        "Game Rules:",
        "1. Set the maze nesting level (1-5).",
        "2. After setting, click 'Start Game' to play.",
        "3. Collect points in the main maze.",
        "4. Reach 60 points in the main maze to win!",
        "PS: You can also choose AI to play the game.",
    ]

    # 创建一个关闭按钮
    close_button = pygame.Rect(screen_width // 2 - 50, screen_height - 100, 100, 40)

    while True:
        screen.fill((255, 255, 255))  # 背景填充白色

        # 显示规则文本
        y_offset = 50
        for rule in rules:
            rule_text = font.render(rule, True, (0, 0, 0))
            screen.blit(rule_text, (screen_width // 2 - rule_text.get_width() // 2, y_offset))
            y_offset += 30

        # 绘制关闭按钮
        pygame.draw.rect(screen, (255, 0, 0), close_button)
        close_text = font.render("Close", True, (255, 255, 255))
        screen.blit(close_text, (close_button.x + 10, close_button.y + 5))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 点击关闭按钮返回主菜单
                if close_button.collidepoint(event.pos):
                    return

        pygame.display.update()



if __name__ == '__main__':

    pygame.init()
    screen = pygame.display.set_mode([screen_width, screen_height])
    pygame.display.set_caption('Maze')

    clock = pygame.time.Clock()
    player = pygame.image.load("user.png").convert_alpha()
    player = pygame.transform.smoothscale(player, (8, 8))
    pygame.mixer.init()
    footstep_sound = pygame.mixer.Sound("脚步声.wav")
    win_sound = pygame.mixer.Sound("胜利.wav")
    correct_sound = pygame.mixer.Sound("回答正确.wav")
    wrong_sound = pygame.mixer.Sound("回答错误.wav")
    running = True  # 控制整个程序是否运行
    game_running = False  # 控制是否在游戏中
    path_trail=[]
    while running:
        if not game_running:
            # 显示主菜单
            max_nesting_level = show_main_menu()
            if max_nesting_level is not None:
                print(f"Max nesting level set to: {max_nesting_level}")
                reset_game()  # 初始化游戏
                game_running = True  # 进入游戏
        else:
            # 游戏逻辑循环
            player_points = 0  # 初始化玩家分数
            win_screen = False  # 标记是否胜利
            current_task = None  # 当前任务
            task_prompt_displayed = False  # 跟踪任务提示窗口的状态

            # 初始化起点位置
            start_x, start_y = x, y  # 记录初始起点位置
            last_x, last_y = x, y  # 光标的当前位置
            player_pos = (start_x, start_y)  # 记录玩家当前位置
            move_stack = []  # 玩家移动栈



            while game_running:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        sys.exit()

                    if event.type == pygame.MOUSEBUTTONDOWN:
                        mouse_pos = pygame.mouse.get_pos()

                        # 检查是否点击了退出按钮
                        if exit_x <= mouse_pos[0] <= exit_x + exit_width and exit_y <= mouse_pos[1] <= exit_y + exit_height:
                            game_running = False  # 返回主菜单

                        # 检查是否点击了AI按钮
                        elif ai_x <= mouse_pos[0] <= ai_x + ai_width and ai_y <= mouse_pos[1] <= ai_y + ai_height:
                            print("AI button clicked")
                            ai_found_exit = ai_move()
                            if ai_found_exit:
                                win_screen = True
                                font = pygame.font.Font(None, 32)
                                print_text(font, 150, 150, "AI Found Exit!", color.Red)
                                pygame.display.flip()
                                time.sleep(2)  # 暂停2秒以显示胜利信息
                                reset_game()

                        # 检查是否点击了返回按钮
                        elif show_return_button and go_back_x <= mouse_pos[0] <= go_back_x + go_back_width and go_back_y <=mouse_pos[1] <= go_back_y + go_back_height:
                            print("Return button clicked")
                            # 将玩家位置重置为起点
                            screen.fill(color.White, (last_x, last_y, player.get_width(), player.get_height()))  # 清除光标之前的位置
                            x, y = start_x, start_y
                            roomx, roomy = 0, 0  # 确保光标从起点开始，更新房间坐标
                            move_stack.clear()  # 清除玩家的移动栈
                            task_prompt_displayed = False  # 重置任务提示显示状态
                            maze_steps = 0  # 重置步骤计数

                            # 只需要重新绘制光标，而不重新绘制迷宫

                            screen.blit(player, (x, y))  # 绘制玩家光标
                            pygame.display.update()

                        # 检查任务点触发
                        player_rect = pygame.Rect(x, y, player.get_width(), player.get_height())
                        for task_point in task_points:
                            task_x_pos = 25 + task_point[0] * maze.room_size
                            task_y_pos = 25 + task_point[1] * maze.room_size
                            task_rect = pygame.Rect(task_x_pos, task_y_pos, maze.room_size, maze.room_size)

                            if player_rect.colliderect(task_rect) and not task_prompt_displayed:
                                # 玩家与任务点重叠且提示尚未显示，显示任务提示
                                if display_task_prompt(Task.generate_random_task(1, task_point)):
                                    success, player_points = display_task_window(Task.generate_random_task(1, task_point),
                                                                                 player_points)
                                    if success:
                                        task_points.remove(task_point)  # 任务完成后移除任务点

                                task_prompt_displayed = True
                                break

                        # 如果玩家离开任务点，重置 task_prompt_displayed 标志
                        if not any(player_rect.colliderect(
                                pygame.Rect(25 + tp[0] * maze.room_size, 25 + tp[1] * maze.room_size, maze.room_size,
                                            maze.room_size)) for tp in task_points):
                            task_prompt_displayed = False

                    # 初始化标志变量，用于跟踪是否显示过分数不足的提示
                    score_warning_shown = False

                    if event.type == pygame.KEYDOWN:
                        # 检查是否到达终点
                        if roomx == maze.room_m - 1 and roomy == maze.room_n - 1:
                            # 玩家到达终点
                            if player_points >= 60:
                                win_sound.play()
                                if not confirm_window_shown:
                                    enter_next_maze = display_win_confirm()
                                    if enter_next_maze:
                                        reset_game()  # 进入下一个迷宫，光标回到起点
                                    win_screen = False
                                    confirm_window_shown = True
                                else:
                                    confirm_window_shown = False
                            else:
                                # 分数不够，显示提示
                                wrong_sound.play()
                                font = pygame.font.Font(None, 32)
                                print_text(font, 150, 150, "Not enough points!", color.Red)
                                pygame.display.flip()
                                pygame.time.wait(1000)  # 暂停1秒显示提示
                                # 设置标志为已经显示过提示
                                score_warning_shown = True
                                # 清除提示文本但不影响其他元素
                                screen.fill(color.White, (150, 150, 200, 50))
                                draw_main_maze_with_markers()  # 重新绘制迷宫、任务点和光标
                                screen.blit(player, (x, y))  # 重新绘制玩家光标
                                pygame.display.update()


                        # 如果提示已显示过，允许玩家正常移动
                        player_rect = pygame.Rect(x, y, player.get_width(), player.get_height())
                        # 清除当前光标位置
                        screen.fill(color.White, (x, y, player.get_width(), player.get_height()))

                        if event.key == pygame.K_RIGHT:
                            if roomx < maze.room_m - 1 and not r_list[roomx][roomy].walls[1]:  # 确保不越界且右边无墙
                                x += maze.room_size
                                roomx += 1
                                maze_steps += 1
                                move_stack.append((x, y))  # 将当前位置压入栈
                                footstep_sound.play()
                                # 记录光标的当前位置，用于后续清除
                                last_x, last_y = x, y
                            else:  # 右边有墙
                                maze_steps += 1
                                font = pygame.font.Font(None, 32)
                                screen.fill(color.White, (150, 0, 200, 25))
                                print_text(font, 150, 0, "This is a wall!", color.Black)

                        elif event.key == pygame.K_LEFT:
                            if roomx > 0 and not r_list[roomx][roomy].walls[3]:  # 确保不越界且左边无墙
                                x -= maze.room_size
                                roomx -= 1
                                maze_steps += 1
                                move_stack.append((x, y))  # 将当前位置压入栈
                                footstep_sound.play()
                                # 记录光标的当前位置，用于后续清除
                                last_x, last_y = x, y
                            else:  # 左边有墙
                                maze_steps += 1
                                font = pygame.font.Font(None, 32)
                                screen.fill(color.White, (150, 0, 200, 25))
                                print_text(font, 150, 0, "This is a wall!", color.Black)

                        elif event.key == pygame.K_UP:
                            if roomy > 0 and not r_list[roomx][roomy].walls[0]:  # 确保不越界且上边无墙
                                y -= maze.room_size
                                roomy -= 1
                                maze_steps += 1
                                move_stack.append((x, y))  # 将当前位置压入栈
                                footstep_sound.play()
                                # 记录光标的当前位置，用于后续清除
                                last_x, last_y = x, y
                            else:  # 上边有墙
                                maze_steps += 1
                                font = pygame.font.Font(None, 32)
                                screen.fill(color.White, (150, 0, 200, 25))
                                print_text(font, 150, 0, "This is a wall!", color.Black)

                        elif event.key == pygame.K_DOWN:
                            if roomy < maze.room_n - 1 and not r_list[roomx][roomy].walls[2]:  # 确保不越界且下边无墙
                                y += maze.room_size
                                roomy += 1
                                maze_steps += 1
                                move_stack.append((x, y))  # 将当前位置压入栈
                                footstep_sound.play()
                                # 记录光标的当前位置，用于后续清除
                                last_x, last_y = x, y
                            else:  # 下边有墙
                                maze_steps += 1
                                font = pygame.font.Font(None, 32)
                                screen.fill(color.White, (150, 0, 200, 25))
                                print_text(font, 150, 0, "This is a wall!", color.Black)

                        elif event.key == pygame.K_ESCAPE:
                            # 玩家按下 ESC 键退出当前迷宫，返回到上一个迷宫
                            x, y = start_x, start_y # 将玩家位置重置为起点
                            reset_game()
                            continue

                        # 如果玩家回退，弹出栈顶并清除当前路径印记
                        if event.key == pygame.K_b and move_stack:
                            last_position = move_stack.pop()  # 弹出栈顶位置
                            x, y = last_position
                            # 清除之前留下的光标
                            screen.fill(color.White, (x, y, player.get_width(), player.get_height()))
                            pygame.display.flip()

                        # 重置分数不足提示标志以避免重复提示
                        if not (roomx == maze.room_m - 1 and roomy == maze.room_n - 1):
                            score_warning_shown = False

                        # 检查是否触发任务点
                        success, player_points = check_task_trigger(x, y, task_points, player_points)
                        if success:
                            # 重新绘制迷宫和玩家位置
                            draw_main_maze_with_markers()
                            screen.blit(player, (x, y))
                            pygame.display.update()
                            continue  # 跳过当前帧，等待玩家下一步输入

                        # 重新绘制光标
                        screen.blit(player, (x, y))
                        pygame.display.update()

                # 绘制返回按钮
                if show_return_button:
                    pygame.draw.rect(screen, color.Gray, [go_back_x, go_back_y, go_back_width, go_back_height])
                    font = pygame.font.Font(None, 36)
                    text = font.render(go_back_text, True, color.Black)
                    text_rect = text.get_rect(center=(go_back_x + go_back_width // 2, go_back_y + go_back_height // 2))
                    screen.blit(text, text_rect)

                # 画退出按钮
                pygame.draw.rect(screen, color.Gray, [exit_x, exit_y, exit_width, exit_height])
                font = pygame.font.Font(None, 36)
                text = font.render(exit_text, True, color.Black)
                text_rect = text.get_rect(center=(exit_x + exit_width // 2, exit_y + exit_height // 2))
                screen.blit(text, text_rect)

                # 画AI按钮
                ai_rect = pygame.draw.rect(screen, color.Gray, [ai_x, ai_y, ai_width, ai_height])
                text = font.render(ai_text, True, color.Black)
                text_rect = text.get_rect(center=(ai_x + ai_width // 2, ai_y + ai_height // 2))
                screen.blit(text, text_rect)

                # 画步骤数
                font = pygame.font.Font(None, 32)
                screen.fill(color.White, (25, 0, 200, 25))
                print_text(font, 25, 0, "Steps: " + str(maze_steps), color.Black)

                #记录分数
                font = pygame.font.Font(None, 32)

                print_text(font, 25, 340, f"60 to win : points={player_points}", color.Black)

                pygame.display.update()
                clock.tick(20)
